package com.example.util;

import org.springframework.data.redis.core.StringRedisTemplate;

import redis.clients.jedis.Jedis;

/**redis 锁实现
 * @author Administrator
 *
 */
public class SpringRedisLockUtiles {

	//数据字段锁1秒超时
	private Long TIMEOUT_SECOUND = 1000L;
	private static SpringRedisLockUtiles utils;
	private StringRedisTemplate client;
	private final String LOCK_PREFIX="spring_redis_lock_";
	private SpringRedisLockUtiles(StringRedisTemplate client)
	{
		this.client=client;
	}
	
	
	public static synchronized SpringRedisLockUtiles getInstance(StringRedisTemplate client)
	{
		if(utils==null)
		{
			utils=new SpringRedisLockUtiles(client);
		}
		return utils;
	}
	
	/** 
	*  获取指定数据的lock
	* @param key   该类型数据的唯一标识
	* @return Boolean
	* @author liuhuaqing
	* @date 2018年7月5日下午6:07:02
	*/ 
	/** 
	*
	* @param key  
	* @param flag  超过等待时间是否强制由当前线程释放锁
	* @param time   释放锁的等待时间
	* @return Boolean
	* @author liuhuaqing
	* @date 2018年7月5日下午6:58:28
	*/ 
	public Boolean lock(String key,Boolean flag,Long time)
	{
		
		
	   while(client.opsForValue().setIfAbsent(getKey(key),String.valueOf(System.currentTimeMillis()))){
	       
		   Long lockTime = Long.valueOf(client.opsForValue().get(getKey(key)));
	       //如果该字段超过锁定时间则释放
		   if (flag&&lockTime!=null && System.currentTimeMillis() > lockTime+time) {
	            client.delete(getKey(key));
            }
	   }
	   
	   return true;
	}
	
	
	public Boolean lock(String key,Boolean flag)
	{
		return lock(key, flag, TIMEOUT_SECOUND);
	}
	
	
	public Boolean lock(String key)
	{
		return lock(key, true);
	}
	
	
	
	/** 
	* 解锁
	* @param key void
	* @author liuhuaqing
	* @date 2018年7月5日下午6:12:26
	*/ 
	public  void unLock(String key)
	{
		 client.delete(getKey(key));
	}
	
	
	private String getKey(String id)
	{
		return LOCK_PREFIX+id;
	}
}
